package independence.remoting;

import java.util.Set;

import org.red5.annotations.DeclarePrivate;
import org.red5.server.api.IClient;
import org.red5.server.api.IConnection;
import org.red5.server.api.IContext;
import org.red5.server.api.IScope;
import org.red5.server.api.Red5;
import org.red5.server.api.ScopeUtils;
import org.red5.server.api.so.ISharedObject;
import org.red5.server.api.so.ISharedObjectService;

/**
 * The AbstractRemotingHandler class serves as an abstract base class for creating
 * classes which serve as remoting gateways. Extend this class to easily create remoting
 * handlers which will be completely aware of the current scope, connection, client and context.<br><br>
 * 
 * This class provides access to utility methods for quickly and easily getting access
 * to:
 * <ul>
 * 	<li>The current IScope, IClient, IConnection, and IContext associated with the current thread.</li>
 * 	<li>SharedObject control as per {@link org.red5.server.api.so.ISharedObjectService}. Provides 
 * 		methods for creating, clearing, getting SharedObjects, as well as testing if they exist.</li>
 * </ul>
 * 
 * @see org.red5.server.api.so.ISharedObjectService
 * @author TK, TK Assembled for Independence - Honor.
 */
public class AbstractRemotingHandler implements ISharedObjectService {
	/**
	 * Gets the scope in which the current thread is operating.
	 * @return	<IScope> The scope in which the current thread is operating.
	 */
	@DeclarePrivate public IScope getScope() {
		return new Red5().getScope();
	}
	/**
	 * Gets the client object associated with the current connection that is operating
	 * in this scope on the current thread.
	 * @return	<IClient> The IClient object associated with the current connection's client.
	 */
	@DeclarePrivate public IClient getClient() {
		return new Red5().getClient();
	}
	/**
	 * Gets the connection associated with the current running thread.
	 * @return	<IConnection> The IConnection instance associated with the current thread.
	 */
	@DeclarePrivate public IConnection getConnection() {
		return new Red5().getConnection();
	}
	/**
	 * Gets the connection-local, the current client's active connection associated with the
	 * currently running thread.
	 * @return	<IConnection> The connection-local to the current client.
	 */
	@DeclarePrivate public IConnection getConnectionLocal() {
		return Red5.getConnectionLocal();
	}
	/**
	 * Gets the current Spring application context.
	 * @return	<IContext> The current Spring application context.
	 */
	@DeclarePrivate public IContext getContext() {
		return new Red5().getContext();
	}
	/** {@inheritDoc} */
	@DeclarePrivate
	@Override public boolean clearSharedObjects(IScope scope, String path) {
		return getSharedObjectService(scope).clearSharedObjects(scope, path);
	}
	/** {@inheritDoc} */
	@DeclarePrivate
	@Override public boolean createSharedObject(IScope scope, String name, boolean persistent) {
		return getSharedObjectService(scope).createSharedObject(scope, name, persistent);
	}
	/** {@inheritDoc} */
	@DeclarePrivate
	@Override public ISharedObject getSharedObject(IScope scope, String name) {
		return this.getSharedObject(scope, name, false);
	}
	/** {@inheritDoc} */
	@DeclarePrivate
	@Override public ISharedObject getSharedObject(IScope scope, String name, boolean persistent) {
		return getSharedObjectService(scope).getSharedObject(scope, name, persistent);
	}
	/** {@inheritDoc} */
	@DeclarePrivate
	@Override public Set<String> getSharedObjectNames(IScope scope) {
		return getSharedObjectService(scope).getSharedObjectNames(scope);
	}
	/** {@inheritDoc} */
	@DeclarePrivate
	@Override public boolean hasSharedObject(IScope scope, String name) {
		return getSharedObjectService(scope).hasSharedObject(scope, name);
	}
	/**
	 * Returns the SharedObjectService for the scope provided.
	 * @param	scope	<IScope> The scope under which to get the SharedObjectService.
	 * @return	The SharedObjectService object by which to perform SharedObject operations.
	 */
	@DeclarePrivate protected ISharedObjectService getSharedObjectService(IScope scope) {
		return (ISharedObjectService) ScopeUtils.getScopeService(scope,
				ISharedObjectService.class, false);
	}
}
